/***********************************************************************
*                                                                      *
*               This software is part of the ECharts package           *
*                  Copyright (c) 2006-2008 AT&T Corp.                  *
*                      and is licensed under the                       *
*                  Common Public License, Version 1.0                  *
*                            by AT&T Corp.                             *
*                                                                      *
***********************************************************************/
// $Name:  $ $Id: $

package org.echarts.servlet.sip.features.registrar;

import java.util.Iterator;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.echarts.monitor.InfoEvent;
import org.echarts.servlet.sip.EChartsProxyServletToJava;
import org.hibernate.Query;
import org.hibernate.Session;

import com.germinus.telcoblocks.echarts.db.BindingExt;
import com.germinus.telcoblocks.echarts.db.HibernateUtil;

public class RegistrarServletToJavaImpl extends EChartsProxyServletToJava implements RegistrarServletToJava{


	
	private Timer timer;
	
	public void start() throws Exception {
		HibernateUtil.getSessionFactory();
		timer = new Timer();
		timer.schedule(new Scavenger(), 5000, 5000);
	}
	
	public void stop() throws Exception {
		timer.cancel();
		HibernateUtil.getSessionFactory().close();
	}


	private static final Pattern SIP_USER_PATTERN = Pattern.compile("^sip:(.*)@.*");

	public BindingExt getBinding(String addressOfRecord) {
		List<BindingExt> bindings = getBindings(addressOfRecord);		
		Iterator<BindingExt> it = bindings.iterator();		
		BindingExt binding = (BindingExt) it.next();
		
		return binding;
	}
	
	public BindingExt createBinding(String aor, String contact) {
		return new BindingExt(aor, contact);
	}

	public String getUser(String addressOfRecord) {
		String user = null;
		Matcher matcher = SIP_USER_PATTERN.matcher(addressOfRecord);
		if (matcher.find()) user = matcher.group(1);
		putEvent(new InfoEvent("found user: " + user + " in address of record: " + addressOfRecord));
		return user;
	}
	
	public void addBinding(String addressOfRecord, Binding binding) {
		
		
		List<BindingExt> bindings = getBindings(addressOfRecord);
		if (bindings.size()>0){			
			Iterator<BindingExt> it = bindings.iterator();
			while (it.hasNext()) {
				beginTransaction();
				BindingExt bindingExt = (BindingExt) it.next();
				bindingExt.setCallId(binding.callId);
				bindingExt.setContactAddress(binding.contactAddress);
				bindingExt.setexpiresTime(binding.expiresTime);
				bindingExt.setLastCSeq(binding.lastCSeq);	
				getSession().update(bindingExt);
				commitTransaction();
			}
		}
		else{
			beginTransaction();
			BindingExt bindingExt = new BindingExt(addressOfRecord,getUser(addressOfRecord));
			bindingExt.setCallId(binding.callId);
			bindingExt.setContactAddress(binding.contactAddress);
			bindingExt.setexpiresTime(binding.expiresTime);
			bindingExt.setLastCSeq(binding.lastCSeq);
			getSession().save(bindingExt);
			commitTransaction();
		}
			
		
	}
	
	public List<BindingExt> getBindings(String aor) {
		beginTransaction();
		List<BindingExt> bindingList= getSession().createQuery("FROM BindingExt b where b.aor=:aor").setParameter("aor", aor).list();
		commitTransaction();
		return bindingList;
				
	}
	
	public List<BindingExt> getAllBindings() {
		beginTransaction();
		List<BindingExt> bindingList= getSession().createQuery("FROM BindingExt b").list();		
		commitTransaction();
		return bindingList;
	}
	
	public void removeBinding(String addressOfRecord) {
		
		List<BindingExt> bindings = getBindings(addressOfRecord);
		beginTransaction();
		Iterator<BindingExt> it = bindings.iterator();
		while (it.hasNext()) {
			BindingExt binding = (BindingExt) it.next();
			getSession().delete(binding);
		}
		commitTransaction();
	}
	
	public void beginTransaction() {
		getSession().beginTransaction();
	}
	
	public void commitTransaction() {
		getSession().getTransaction().commit();
	}

	public void rollbackTransaction() {
		getSession().getTransaction().rollback();
	}
	private Session getSession() {
		return HibernateUtil.getSessionFactory().getCurrentSession();
	}
	
	public void removeExpiredBindings() {
		Session session = getSession();
		Query query = session.createQuery("FROM BindingExt WHERE expiresTime < :now");
		query.setParameter("now", System.currentTimeMillis());
		Iterator<BindingExt> it = query.iterate();
		while (it.hasNext()) {
			BindingExt binding = (BindingExt) it.next();
			session.delete(binding);
		}
	}
	class Scavenger extends TimerTask {
		public void run() {
			try {
				beginTransaction();
				removeExpiredBindings();
			} finally {
				commitTransaction();
			}
		}
	}
}
